package com.b2mining.integration.helper;

import java.io.InputStream;
import java.sql.*;

import org.apache.log4j.Logger;

/**
 * Clase que permite la conexion con la Base De Datos.
 * @since (7/3/2003 10:35:26 AM)
 * @author Synopsis S.A. <BR>
 * Analista Programador: Miguel Lora G., Janyn Roca
 * 						
 */
public class BDHelper {
	private static java.lang.String driverClass;
	private static java.lang.String schema;
	private static java.lang.String userid;
	private static java.lang.String password;
	private static java.lang.String urldb;
	private static InputStream is;
	
	private static boolean isConnected=true;
	private static String errorConexion;
	
	static {
		Logger log = Logger.getLogger(BDHelper.class);
		try {
			
			userid = Helper.user;
			password = Helper.password;
			driverClass = Helper.driver;
			schema = Helper.schema;
			urldb = Helper.url;
			Class.forName(driverClass);			

		} catch (Exception e) {
			log.debug("BDHelper error :" + e);
		} finally {
			try {
				if (is != null)
					is.close();
			} catch (Exception e) {
				log.debug(
					"BDHelper error al cerrar el archivo properties");
			}
		}
	}
	
	
	/**
	 * Metodo que establece la conexion con la Base de Datos.
	 * @return Connection la conexion con la Base de Datos.
	 */	
	public static java.sql.Connection getConnectionA() {
		Logger log = Logger.getLogger(BDHelper.class);
		try{
			isConnected=true;	
			return DriverManager.getConnection(urldb,userid,password);

		}
		catch(Exception e){
			log.debug("Error en BDHelper.getConnection(): "+ e);
			isConnected=false;
			return null;
		}
	}

	public static Connection getConnection() throws SQLException {
        /**
         * The following lines try to resolve 'Address already in use: connect'
         * error by trying to re-connect after a few seconds
         */
		Logger log = Logger.getLogger(BDHelper.class);
        Connection connection = null;
        byte tryCount = 0;
        while (connection == null) {
            try {
            	long ini = System.currentTimeMillis();
                connection = DriverManager.getConnection(urldb, userid, password);
                long fin = System.currentTimeMillis();
                System.out.println("Get Connection time "+((fin-ini)/1000));
                //log.debug("*** Connection successful!");
            } 
            catch (SQLException ex) {
                if (++tryCount > 5) {
                	log.debug("Error en BDHelper.getConection "+ex.getMessage());
                    throw ex;
                } 
                else {
                    connection = null;
                    //ex.printStackTrace();
                    log.debug("*** No se pudo conectar a la base de datos, reintentando conectar en 5 segundos..." +ex.getMessage());
                    try {
                        Thread.sleep(5000);
                    } 
                    catch (InterruptedException iex) {
                    } // try
                } // if (++tryCount > 5)
            } // try
        } // while
        
        return connection;
    }
	
	
	/**
	 * Metodo que consulta en tabla Correlativo el siguiente id a usar para una tabla
	 * @param table el nombre de la tabla para la cual se esta buscando el siguiente id
	 * @return correlativo el siguiente id a utilizar para la insercion.
	 */	
	public static synchronized int getNextID(java.lang.String table) {
		Logger log = Logger.getLogger(BDHelper.class);
		Connection con=null;
		PreparedStatement st1=null, st2=null;
		ResultSet rs=null;
		int correlative = -1;
		try{
			log.debug("Sacando el next ID "+table);
			con = getConnection();
			con.setAutoCommit(false);
			String query = "select correlative from "+BDHelper.getSchema()+"correlativo where tablename=?";
			String increment = "update "+BDHelper.getSchema()+"correlativo set correlative=? where tablename=?";
			st1 = con.prepareStatement(query);
			st1.setString(1, table.trim().toUpperCase());
			rs = st1.executeQuery();
			if (rs.next()){
				correlative = rs.getInt(1);
				log.debug("Correlativo "+correlative);
			}
			st2=con.prepareStatement(increment);
			st2.setInt(1,correlative+1);
			st2.setString(2,table.trim().toUpperCase());
			st2.execute();
			con.commit();
			log.debug("Actualizo la tabla "+table+" en correlativo");
		}
		catch(Exception e){
			log.debug("Error al obtener el ID de la tabla "+table+" error "+e.getMessage());
			try{
				con.rollback();
			}catch(Exception ex){}
			log.debug(""+e);
		}finally{
			try{
				if (rs!=null) rs.close();
				if (st1!=null) st1.close();
				if (st2!=null) st2.close();
				if (con!=null) con.close();
			}catch(Exception ex){}
		}
		return correlative;
	}
	
	
	/**
	 * Metodo que devuelve el nombre del esquema utilizado en la Base de Datos.
	 * @return schema el esquema de la base de datos obtenido del archivo de propiedades.
	 */	
	public static java.lang.String getSchema() {
		// TODO: implement
		return schema;
	}

	/**
	 * Returns the isConnected.
	 * @return boolean
	 */
	public static boolean isConnected() {
		return isConnected;
	}

	/**
	 * Sets the isConnected.
	 * @param isConnected The isConnected to set
	 */
	public static void setIsConnected(boolean isConnected) {
		BDHelper.isConnected = isConnected;
	}

	/**
	 * Returns the errorConexion.
	 * @return String
	 */
	public static String getErrorConexion() {
		return errorConexion;
	}

	/**
	 * Sets the errorConexion.
	 * @param errorConexion The errorConexion to set
	 */
	public static void setErrorConexion(String errorConexion) {
		BDHelper.errorConexion = errorConexion;
	}

}